// struct:（对比js中的类）结构体，自定义的数据类型，为相关联的值命名，打包 => 有意义的组合
// 定义struct
// 实例化struct：创建struct实例，为每个字段指定具体的值
// 一旦struct是可变的那么所有的值都是可以改变的
// 更新语法在某个struct实例来创建一个新的实例类似于js的扩展运算符，只是扩展运算符放在最后
// tuple struct
// unit-like struct没有任何字段
// 适用于在某个类型上实现某个trait，但是却不想存储任何数据
// struct所有权，拥有自身数据的所有权
// 只要struct有效那么内部的数据也是有效的

// struct方法
// 方法和函数类型：fn关键字、名称、参数、返回值
// 方法和函数的不同之处
// 1.方法是在struct或者enum、trait对象的上下文中定义
// 2.需要一个impl关键字，第一个参数都是self（可以获得所有权也可以不用），表示方法被调用的struct实例
// 关联函数
// 可以在impl块中定义不把self作为第一个参数的函数，叫做关联函数（不是方法）例如：String::from()
// 关联函数通常用于构造器
// 每个struct允许多个impl

struct User {
    username: String,
    email: String,
    age: u64,
    active: bool,
}

// tuple struct
struct Color(i32, i32, i32);

// struct方法和关联函数
impl User {
    fn test(&self, arg: u32) -> u64 {
        println!("{},{}, {}", self.age, self.email, arg);
        return self.age
    }
    fn test1(self, arg: u32) -> String {
        println!("{},{}, {}", self.age, self.email, arg);
        return self.email
    }

    fn test2(arg: u32) -> u32 {
        return arg
    }
}

fn main() {
    let mut user1 = User {
        username: String::from("username"),
        email: String::from("email"),
        active: true,
        age: 136,
    };
    let mut user3 = User {
        username: String::from("username"),
        email: String::from("email"),
        active: true,
        age: 136,
    };
    user1.username = String::from("username111");
    let user2 = User {
        username: String::from("test111"),
        ..user3
    };
    let b = getuser(String::from("test"));
    println!(
        "{},{},{},{},{},{}",
        user1.email, user1.username, user1.active, user1.age, b.age, user2.username
    );
    let black = Color(0, 0, 0);
    println!("hello world,{}", black.0);

    let user4 = User {
        username: String::from("username"),
        email: String::from("email"),
        active: true,
        age: 136,
    };

    let test2 = User::test2(12345);
    println!("{}, {}, {}", user4.test(111), user4.test1(324567), test2);
}

fn getuser(email: String) -> User {
    return User {
        username: String::from("username"),
        email,
        active: true,
        age: 136,
    };
}
